# coding: utf-8

import re
from copy import deepcopy
import tkinter
import tkinter.filedialog as dialog
import time
import os
import json
import sys

reString = re.compile(r"^00\|.*?\|.*?\|.*?\|.*?\|[0-9a-f]*?$")
special = {
    "\ue033": "品级",
    "\ue03c": "(HQ)",
    "\ue090": "①",
    "\ue091": "②",
    "\ue092": "③",
    "\ue093": "④",
    "\ue094": "⑤",
    "\ue095": "⑥",
    "\ue096": "⑦",
    "\ue097": "⑧",
    "\ue0bb": "",
    "\ue071": "Ⓐ",
    "\ue072": "Ⓑ",
    "\ue073": "Ⓒ"
}
codeToMessage = { # 网页Class用
    "000a": "Speak",
    "001e": "Yell",
    "000b": "Shout",
    "000e": "Party",
    "0025": "CwLink1",
    "0065": "CwLink2",
    "0066": "CwLink3",
    "0067": "CwLink4",
    "0068": "CwLink5",
    "0069": "CwLink6",
    "006a": "CwLink7",
    "006b": "CwLink8",
    "0010": "LinkShell1",
    "0011": "LinkShell2",
    "0012": "LinkShell3",
    "0013": "LinkShell4",
    "0014": "LinkShell5",
    "0015": "LinkShell6",
    "0016": "LinkShell7",
    "0017": "LinkShell8",
    "001b": "Beginner",
    "000d": "Tell",
    "000c": "Tell",
    "001d": "Motion",
    "001c": "Motion",
    "0018": "FreeCompany",
    "000f": "Alliance"
}
engToChn = {
    "Speak": "说话",
    "Yell": "呼喊",
    "Shout": "喊话",
    "Party": "小队",
    "Tell": "悄悄话",
    "CwLink1": "跨服贝1",
    "CwLink2": "跨服贝2",
    "CwLink3": "跨服贝3",
    "CwLink4": "跨服贝4",
    "CwLink5": "跨服贝5",
    "CwLink6": "跨服贝6",
    "CwLink7": "跨服贝7",
    "CwLink8": "跨服贝8",
    "LinkShell1": "通讯贝1",
    "LinkShell2": "通讯贝2",
    "LinkShell3": "通讯贝3",
    "LinkShell4": "通讯贝4",
    "LinkShell5": "通讯贝5",
    "LinkShell6": "通讯贝6",
    "LinkShell7": "通讯贝7",
    "LinkShell8": "通讯贝8",
    "Beginner": "新频",
    "Motion": "情感动作",
    "FreeCompany": "部队",
    "Alliance": "团队"
}
color_translate = {
    11: "255,255,255", 12: "255,189,189", 13: "255,222,199", 14: "255,247,176",
    21: "247,247,247", 22: "255,0,0",     23: "255,127,0",   24: "255,255,0",
    31: "222,222,222", 32: "255,74,74",   33: "255,166,102", 34: "255,255,176",
    41: "214,214,214", 42: "255,125,125", 43: "255,204,171", 44: "255,222,115",
    51: "204,204,204", 52: "255,191,191", 53: "255,102,0",   54: "240,199,107",
    61: "189,189,189", 62: "214,191,191", 63: "214,102,107", 64: "204,204,102",
    71: "166,166,166", 72: "196,161,161", 73: "214,189,171", 74: "199,191,158",
    15: "232,255,224", 16: "229,255,252", 17: "156,207,242", 18: "255,219,255",
    25: "0,255,0",     26: "0,255,255",   27: "0,0,255",     28: "255,0,255",
    35: "127,255,0",   36: "186,255,240", 37: "0,127,255",   38: "224,94,143",
    45: "127,247,94",  46: "102,229,255", 47: "148,191,255", 48: "255,138,196",
    55: "212,255,125", 56: "171,219,229", 57: "127,127,255", 58: "255,184,222",
    65: "171,214,71",  66: "176,229,229", 67: "178,138,255", 68: "222,166,186",
    75: "56,229,178",  76: "59,229,229",  77: "222,191,247", 78: "222,135,242"
}
chnToEng = {j: i for (i, j) in engToChn.items()}
codeFormat = deepcopy(codeToMessage) # 消息串用
codeFormat["000c"] = "TellToOther" # 000c 是发给别人的  000d是收到的悄悄话
codeFormat['001d'] = "MotionR" # 001d 是内置情感动作

tkWindow = tkinter.Tk()
tkWindow.withdraw()

maxCount = 3
targetFileLoc = ""

def replaceSpecial(info) -> str:
    global special
    for i in list(special.keys()):
        info = info.replace(i, special[i])
    return info

class genHTML():
    def __init__ (self):
        self.logs = []
        self.message = []
        self.raw_logs = ""
        self.pretty_msg = []
        self.template = ''
        self.filename = ''
        self.html_code = []
    
    def search(self):
        global targetFileLoc, reString
        with open(targetFileLoc, 'r', encoding="utf-8") as logfile:
            self.raw_logs = logfile.read()
        print("Matching... ", end="", flush=True)
        self.logs = self.raw_logs.split('\n')
        for i in self.logs:
            if reString.findall(i):
                temp = reString.findall(i)[0].split('|')
                timestamp = temp[1].split('.')[0]
                the_time = time.strptime(timestamp, "%Y-%m-%dT%H:%M:%S")
                message_type = temp[2]
                if message_type not in list(codeToMessage.keys()):
                    continue
                name = replaceSpecial(temp[3])
                message = replaceSpecial(temp[4])
                message_dict = {"time": the_time, "type": message_type, "name": name, "message": message}
                self.message.append(message_dict)
        print("done.")
        self.filename = os.path.split(targetFileLoc)[-1]

    def decorate(self):
        print("Decorating... ", end="", flush=True)
        for i in self.message:
            new_message = {}
            the_class = codeToMessage[i['type']]
            the_type = codeFormat[i['type']]
            new_message['time'] = i['time']
            the_message = ""
            if the_type == "Tell":
                the_message = f"{i['name']}>>> {i['message']}"
            elif the_type == "TellToOther":
                the_message = f">>{i['name']}: {i['message']}"
            elif the_type == "MotionR":
                the_message = i['message']
            elif the_type == "Motion":
                the_message = f"{i['name']}{i['message']}"
            elif "Link" in the_type or the_type in ["FreeCompany", "Alliance", "Beginner"]:
                the_message = f'[{engToChn[the_type].replace("通讯", "")}]{i["name"]}: {i["message"]}'
            elif the_type == "Party":
                the_message = f'<span class="msg_type">[{engToChn[the_type]}]</span>({i["name"]}): {i["message"]}'
            else:
                the_message = f'<span class="msg_type">[{engToChn[the_type]}]</span>{i["name"]}: {i["message"]}'
            the_message = f'<span class="time">[{time.strftime("%H:%M", i["time"])}<span class="sec">{time.strftime(":%S", i["time"])}</span>]</span>' + the_message
            new_message['html'] = f'            <p class="{the_class}">{the_message}</p>'
            self.pretty_msg.append(new_message)
        print('done.')

    def generate(self):
        print("Generating... ", end='', flush=True)
        # print("template.html size: ", end="", flush=True)
        with open("template.html", 'r', encoding='utf-8') as templateFile:
            self.template = templateFile.read()
        self.template = self.template.replace("#FILENAME#", self.filename)
        # print(len(self.template), end="", flush=True)
        now_date = ""
        for i in self.pretty_msg:
            the_date = time.strftime("·%Y年%m月%d日", i['time'])
            if the_date != now_date:
                now_date = the_date
                self.html_code.append(f'            <p><span class="date">{the_date}</span></p>')
            self.html_code.append(i['html'])
        the_html = '\n'.join(self.html_code)
        #print(" the html size: " + str(len(the_html)), end='', flush=True)
        self.template = self.template.replace("<!--INFO-->", the_html)
        # print(" after size: " + str(len(self.template)))
        print("done.")
        return self.template

    def run(self):
        self.search()
        self.decorate()
        return self.generate()

def read_color_config():
    load_json = ''
    with open('color.json', 'r', encoding="utf-8") as json_file:
        load_json = json_file.read()
    if load_json:
        color_config = json.loads(load_json)
    with open("sample.style.html", 'r', encoding="utf-8") as sample_style:
        style_html = sample_style.read()
    for i in color_config.keys():
        the_eng = chnToEng[i]
        the_value = int(color_config[i])
        if the_value not in list(color_translate.keys()):
            the_value = 55
        the_color = color_translate[the_value]
        style_html = style_html.replace(f"#{the_eng}#", f"rgba({the_color},1)")
    return style_html

if __name__ == '__main__':
    while maxCount > 0:
        targetFileLoc = dialog.askopenfilename(filetypes=[("日志文件", "*.log")])
        if targetFileLoc and os.path.isfile(targetFileLoc):
            break
        maxCount -= 1
    if not os.path.isfile(targetFileLoc):
        print("File does not exist. Exit.")
        sys.exit(0)
    print("Target file location: " + targetFileLoc)
    gen = genHTML()
    html_page = gen.run()
    style_html = read_color_config()
    html_page = html_page.replace("<!--STYLE-->", style_html)
    
    maxCount = 3
    while maxCount > 0:
        output_file_loc = dialog.asksaveasfilename(filetypes=[("HTML File", "*.html;*.htm")])
        filename = os.path.split(output_file_loc)[-1]
        if filename:
            break
        maxCount -= 1
    if not output_file_loc:
        print("Cannot save file. Exit.")
        sys.exit(0)
    if '.html' not in output_file_loc[-5:] and '.htm' not in output_file_loc[-4:]:
        output_file_loc = output_file_loc + ".html"
        
    with open(output_file_loc, "w", encoding="utf-8") as output_file:
        output_file.write(html_page)
    print("Output file location: " + output_file_loc)
    sys.exit(0)
